package com.woniuxy.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.user.dto.LoginRequest;
import com.woniuxy.user.dto.LoginResponse;
import com.woniuxy.user.entity.SysUser;
import com.woniuxy.user.mapper.SysUserMapper;
import com.woniuxy.user.mapper.SysUserRoleMapper;
import com.woniuxy.user.service.AuthService;
import com.woniuxy.user.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 认证服务实现类
 */
@Slf4j
@Service
public class AuthServiceImpl implements AuthService {
    
    @Autowired
    private SysUserMapper userMapper;
    
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @Value("${jwt.secret}")
    private String jwtSecret;
    
    @Value("${jwt.expiration}")
    private Long jwtExpiration;
    
    @Value("${flowable.gateway.url:http://localhost:9999}")
    private String flowableGatewayUrl;
    
    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        log.info("处理用户登录，用户名：{}", loginRequest.getUsername());
        
        // 根据用户名查找用户
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", loginRequest.getUsername());
        SysUser user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 验证密码（明文比较）
        log.info("输入密码: {}", loginRequest.getPassword());
        log.info("数据库密码: {}", user.getPassword());
        boolean passwordMatch = loginRequest.getPassword().equals(user.getPassword());
        log.info("密码匹配结果: {}", passwordMatch);
        
        if (!passwordMatch) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 用户状态检查已移除，所有用户都可以登录
        
        // 更新登录信息
        user.setLastLoginTime(LocalDateTime.now());
        user.setLastLoginIp(getClientIpAddress());
        user.setLoginCount(user.getLoginCount() + 1);
        userMapper.updateById(user);
        
        // 获取用户角色信息
        List<String> roleCodes = userRoleMapper.selectRoleCodesByUserId(user.getId());
        List<String> roleNames = userRoleMapper.selectRoleNamesByUserId(user.getId());
        
        // 生成JWT Token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("username", user.getUsername());
        claims.put("realName", user.getRealName());
        claims.put("roles", roleCodes);
        
        String token = jwtUtil.generateToken(user.getUsername(), claims);
        
        // 构建响应
        LoginResponse response = new LoginResponse();
        response.setSuccess(true);
        response.setMessage("登录成功");
        response.setToken(token);
        
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setRealName(user.getRealName());
        userInfo.setEmail(user.getEmail());
        userInfo.setPhone(user.getPhone());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setRoles(roleNames);
        
        response.setUserInfo(userInfo);
        
        // 同步用户到flowable
        syncUserToFlowable(user, roleCodes);
        
        log.info("用户登录成功，用户ID：{}，用户名：{}", user.getId(), user.getUsername());
        return response;
    }
    
    @Override
    public boolean validateToken(String token) {
        try {
            return jwtUtil.validateToken(token);
        } catch (Exception e) {
            log.error("Token验证失败", e);
            return false;
        }
    }
    
    @Override
    public void logout(String token) {
        // 这里可以实现Token黑名单机制
        // 目前简单实现，实际项目中可以将Token加入黑名单
        log.info("用户登出，Token：{}", token.substring(0, Math.min(20, token.length())) + "...");
    }
    
    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress() {
        // 这里应该从HttpServletRequest中获取真实IP
        // 暂时返回模拟IP
        return "127.0.0.1";
    }
    
    /**
     * 同步用户到flowable
     */
    private void syncUserToFlowable(SysUser user, List<String> roleCodes) {
        try {
            // 根据角色代码映射到flowable组ID
            String groupId = mapRoleToFlowableGroup(roleCodes);
            if (groupId != null) {
                String url = flowableGatewayUrl + "/flowable-server/workflow/syncUser";
                Map<String, String> params = new HashMap<>();
                params.put("username", user.getUsername());
                params.put("realName", user.getRealName());
                params.put("email", user.getEmail() != null ? user.getEmail() : "");
                params.put("groupId", groupId);
                
                restTemplate.postForObject(url, params, String.class);
                log.info("用户同步到flowable成功，用户名：{}，组ID：{}", user.getUsername(), groupId);
            }
        } catch (Exception e) {
            log.error("同步用户到flowable失败，用户名：{}", user.getUsername(), e);
        }
    }
    
    /**
     * 将角色代码映射到flowable组ID
     */
    private String mapRoleToFlowableGroup(List<String> roleCodes) {
        if (roleCodes == null || roleCodes.isEmpty()) {
            return null;
        }
        
        // 角色代码到flowable组ID的映射
        Map<String, String> roleGroupMap = new HashMap<>();
        roleGroupMap.put("office_business", "office_business");
        roleGroupMap.put("regional_manager", "regional_manager");
        roleGroupMap.put("regional_director", "regional_director");
        roleGroupMap.put("marketing_manager", "marketing");
        roleGroupMap.put("logistics_director", "logistics_director");
        roleGroupMap.put("sales_director", "sales_director");
        roleGroupMap.put("company_business", "company_business");
        
        // 返回第一个匹配的角色对应的组ID
        for (String roleCode : roleCodes) {
            if (roleGroupMap.containsKey(roleCode)) {
                return roleGroupMap.get(roleCode);
            }
        }
        
        return null;
    }
}

